﻿using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using RawSocketDll;
using WeaponEvalue.Logic;
using WINAPI.User32;

namespace WeaponEvalue
{
    public partial class MainForm : Form
    {
        private GameMonitor[] gameMonitors;
        private string localAddress;
        private RawSocket myRawSock;

        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            gameMonitors = new[]
                               {
                                   new GameMonitor {ID=1,LogTextBox = dataTextBox1, LogLabel = statusLabel1},
                                   new GameMonitor {ID=2,LogTextBox = dataTextBox2, LogLabel = statusLabel2},
                                   new GameMonitor {ID=3,LogTextBox = dataTextBox3, LogLabel = statusLabel3}
                               };

            IPHostEntry hosyEntry = Dns.GetHostEntry(Dns.GetHostName());
            localAddress = hosyEntry.AddressList[1].ToString();
            ipTextBox.Text = localAddress;

            if (hosyEntry.AddressList.Length > 0)
            {
                myRawSock = new RawSocket(hosyEntry.AddressList[1]);
                myRawSock.PacketArrival += DataArrival;
            }
        }

        private void DataArrival(Object sender, RawSocket.PacketArrivedEventArgs e)
        {
            if ("TCP".Equals(e.Protocol, StringComparison.CurrentCultureIgnoreCase))
            {
                if (localAddress.Equals(e.DestinationAddress))
                {
                    if (gameMonitors[0].Enabled && Convert.ToInt32(e.DestinationPort) == gameMonitors[0].GamePort)
                    {
                        var dataHandler = new DataHandler(gameMonitors[0], e);
                        ThreadPool.QueueUserWorkItem(dataHandler.Execute);
                    }
                    if (gameMonitors[1].Enabled && Convert.ToInt32(e.DestinationPort) == gameMonitors[1].GamePort)
                    {
                        var dataHandler = new DataHandler(gameMonitors[1], e);
                        ThreadPool.QueueUserWorkItem(dataHandler.Execute);
                    }
                    if (gameMonitors[2].Enabled && Convert.ToInt32(e.DestinationPort) == gameMonitors[2].GamePort)
                    {
                        var dataHandler = new DataHandler(gameMonitors[2], e);
                        ThreadPool.QueueUserWorkItem(dataHandler.Execute);
                    }
                }
            }
        }

        private void captureButton_Click(object sender, EventArgs e)
        {
            captureButton.Enabled = false;
            stopButton.Enabled = true;
            myRawSock.KeepRunning = true;
            myRawSock.Run();
        }

        private void stopButton_Click(object sender, EventArgs e)
        {
            try
            {
                myRawSock.KeepRunning = false;
                captureButton.Enabled = true;
                stopButton.Enabled = false;
                LogHelper.GetLogger().Flush();
            }
            catch (Exception ex)
            {
            }
        }


        private void getKtzButton1_Click(object sender, EventArgs e)
        {
            gameMonitors[0].F12ButtonPtr = IntPtr.Zero;
            gameMonitors[0].PointComoboBoxPtr = IntPtr.Zero;
            gameMonitors[0].ScriptComoboBoxPtr = IntPtr.Zero;
            User32Dll.EnumWindows(ReportStepOne, "Modified by cc.");
            if (gameMonitors[0].F12ButtonPtr == IntPtr.Zero || gameMonitors[0].ScriptComoboBoxPtr == IntPtr.Zero ||
                gameMonitors[0].PointComoboBoxPtr == IntPtr.Zero)
            {
                MessageBox.Show("KTZ buttons not found!");
            }
        }

        private void getKtzButton2_Click(object sender, EventArgs e)
        {
            gameMonitors[1].F12ButtonPtr = IntPtr.Zero;
            gameMonitors[1].ScriptComoboBoxPtr = IntPtr.Zero;
            gameMonitors[1].PointComoboBoxPtr = IntPtr.Zero;
            User32Dll.EnumWindows(ReportStepOne, "[#] Modified by cc. [#]");
            if (gameMonitors[1].F12ButtonPtr == IntPtr.Zero || gameMonitors[1].PointComoboBoxPtr == IntPtr.Zero ||
                gameMonitors[1].ScriptComoboBoxPtr == IntPtr.Zero)
            {
                MessageBox.Show("KTZ1 buttons not found!");
            }
        }


        public bool ReportStepOne(IntPtr hwnd, string lParam)
        {
            var sb = new StringBuilder(100);
            User32Dll.GetWindowText(hwnd, sb, 100);
            if (sb.ToString().Equals(lParam, StringComparison.CurrentCultureIgnoreCase))
            {
                IntPtr tabPage1 = User32Dll.FindWindowEx(hwnd, IntPtr.Zero, "SysTabControl32", null);
                IntPtr tabPage2 = User32Dll.FindWindowEx(hwnd, tabPage1, "SysTabControl32", null);
                IntPtr tabPage3 = User32Dll.FindWindowEx(hwnd, tabPage2, "SysTabControl32", null);

                IntPtr dialog = User32Dll.FindWindowEx(tabPage1, IntPtr.Zero, null, lParam);
                if (dialog == IntPtr.Zero)
                    dialog = User32Dll.FindWindowEx(tabPage2, IntPtr.Zero, null, lParam);
                if (dialog == IntPtr.Zero)
                    dialog = User32Dll.FindWindowEx(tabPage3, IntPtr.Zero, null, lParam);

                int gameIndex = lParam.StartsWith("[#]") ? 1 : 0;
                if (dialog != IntPtr.Zero)
                {
                    var p = new POINT();
                    p.x = 50;
                    p.y = 200;

                    gameMonitors[gameIndex].F12ButtonPtr = User32Dll.ChildWindowFromPoint(dialog, p);
                    gameMonitors[gameIndex].F12ButtonId = User32Dll.GetDlgCtrlID(gameMonitors[gameIndex].F12ButtonPtr);
                    gameMonitors[gameIndex].MainWindowPtr = dialog;

                    IntPtr temp = User32Dll.FindWindowEx(dialog, IntPtr.Zero, "ComboBox", null);
                    while (temp != IntPtr.Zero)
                    {
                        var stringBuilder = new StringBuilder(100);
                        User32Dll.SendMessage(temp, User32Dll.WM_GETTEXT, new IntPtr(100), stringBuilder);
                        if ("当前点".Equals(stringBuilder.ToString()))
                        {
                            gameMonitors[gameIndex].PointComoboBoxPtr = temp;
                        }
                        else if ("原地打怪".Equals(stringBuilder.ToString()))
                        {
                            gameMonitors[gameIndex].ScriptComoboBoxPtr = temp;
                        }
                        temp = User32Dll.FindWindowEx(dialog, temp, "ComboBox", null);
                    }
                }
                return false;
            }
            return true;
        }

        private void gameComboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(gameComboBox1.SelectedValue.ToString()))
            {
                ipaddressTextBox1.Text = ProcessOperator.GetOpenPort(Convert.ToInt32(gameComboBox1.SelectedValue));
                string[] ip = ipaddressTextBox1.Text.Split(new[] {':'}, StringSplitOptions.RemoveEmptyEntries);
                gameMonitors[0].GamePort = Convert.ToInt32(ip[1]);
            }
            else
            {
                ipaddressTextBox1.Text = string.Empty;
            }
        }


        private void gameStatusCheckBox2_CheckedChanged(object sender, EventArgs e)
        {
            if (gameStatusCheckBox2.Checked)
            {
                npcTextBox2.ReadOnly = true;
                gameMonitors[1].NpcName = npcTextBox2.Text.Trim();
                gameMonitors[1].NpcNameBytes = Encoding.Default.GetBytes(npcTextBox2.Text.Trim());
                gameMonitors[1].Enabled = true;
            }
            else
            {
                npcTextBox2.ReadOnly = false;
                gameMonitors[1].Enabled = false;
            }
        }

        private void gameStatusCheckBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (gameStatusCheckBox1.Checked)
            {
                npcTextBox1.ReadOnly = true;
                gameMonitors[0].NpcName = npcTextBox1.Text.Trim();
                gameMonitors[0].NpcNameBytes = Encoding.Default.GetBytes(npcTextBox1.Text.Trim());
                gameMonitors[0].Enabled = true;
            }
            else
            {
                npcTextBox1.ReadOnly = false;
                gameMonitors[0].Enabled = false;
            }
        }

        private void refreshButton1_Click(object sender, EventArgs e)
        {
            Process[] ges = ProcessOperator.GetRunningProcess();
            gameComboBox1.DisplayMember = "MainWindowTitle";
            gameComboBox1.ValueMember = "Id";
            gameComboBox1.DataSource = ges;
        }

        private void refreshButton2_Click(object sender, EventArgs e)
        {
            Process[] ges = ProcessOperator.GetRunningProcess();
            processComboBox2.DisplayMember = "MainWindowTitle";
            processComboBox2.ValueMember = "Id";
            processComboBox2.DataSource = ges;
        }

        private void processComboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(processComboBox2.SelectedValue.ToString()))
            {
                ipaddresstextBox2.Text = ProcessOperator.GetOpenPort(Convert.ToInt32(processComboBox2.SelectedValue));
                string[] ip = ipaddresstextBox2.Text.Split(new[] {':'}, StringSplitOptions.RemoveEmptyEntries);
                gameMonitors[1].GamePort = Convert.ToInt32(ip[1]);
            }
            else
            {
                ipaddresstextBox2.Text = string.Empty;
            }
        }

        private void musicCheckBox1_CheckedChanged(object sender, EventArgs e)
        {
            gameMonitors[0].PlayMusic = musicCheckBox1.Checked;
        }

        private void autoCheckBox1_CheckedChanged(object sender, EventArgs e)
        {
            gameMonitors[0].AutoOperation = autoCheckBox1.Checked;
        }

        private void musicCheckBox2_CheckedChanged(object sender, EventArgs e)
        {
            gameMonitors[1].PlayMusic = musicCheckBox2.Checked;
        }

        private void autoCheckBox2_CheckedChanged(object sender, EventArgs e)
        {
            gameMonitors[1].AutoOperation = autoCheckBox2.Checked;
        }

        private void clearButton2_Click(object sender, EventArgs e)
        {
            dataTextBox2.Text = string.Empty;
            gameMonitors[1].GamePacketCount = 0;
        }

        private void clearButton3_Click(object sender, EventArgs e)
        {
            dataTextBox3.Text = string.Empty;
            gameMonitors[2].GamePacketCount = 0;
        }


        private void Clear1_Click(object sender, EventArgs e)
        {
            dataTextBox1.Text = string.Empty;
            gameMonitors[0].GamePacketCount = 0;
        }

        private void viewLogButton_Click(object sender, EventArgs e)
        {
            var logForm = new LogForm();
            logForm.Show(this);
        }

        private void testButton_Click(object sender, EventArgs e)
        {
            UIOperator.OperateButton(gameMonitors[1].MainWindowPtr, gameMonitors[1].F12ButtonId);
            UIOperator.OperateDropDown(gameMonitors[1].ScriptComoboBoxPtr, 1);
            UIOperator.OperateDropDown(gameMonitors[1].PointComoboBoxPtr, 1);
        }

        private void crackButton_Click(object sender, EventArgs e)
        {
            var form = new FormAbout();
            form.Show(this);
        }

        private void browseButton_Click(object sender, EventArgs e)
        {
            var openFileDialog = new OpenFileDialog {Filter = "毛|毛.zmy"};

            DialogResult result = openFileDialog.ShowDialog(this);
            while (result != DialogResult.OK)
            {
                result = openFileDialog.ShowDialog(this);
            }

            var sw = new StreamWriter(Application.StartupPath + "\\we.ini");
            sw.WriteLine(openFileDialog.FileName);
            sw.WriteLine(openFileDialog.FileName.Replace("毛", "球"));
            sw.Close();
        }
    }
}